home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS04.ADF / text / inputdevice.txt < prev    next >
Text File  |  1985-12-04  |  18KB  |  456 lines

  1.  
  2. /* input device text */
  3.  
  4.       PRELIMINARY INFORMATION... CURRENTLY UNDER REVIEW.
  5.  
  6.       DOESN'T DESCRIBE THE set mouse port FUNCTIONS.
  7.  
  8.       MAY CONTAIN MINOR INACCURACIES IN THE SAMPLE PROGRAM SEGMENT.
  9.  
  10.       (printed version available approx 11/18/85, reviewed and correct-
  11.       ed).
  12.  
  13.       Rob Peck.
  14.  
  15.  
  16.                                   Chapter 1
  17.  
  18.  
  19.  
  20.                                 Input Device
  21.  
  22.  
  23.  
  24.  
  25.       This chapter describes the Amiga input device, which is a  combi-
  26.       nation of three other devices:  keyboard device, gameport device,
  27.       and timer device.  The input device merges separate  input  event
  28.       streams from the keyboard, mouse, and timer into a single stream.
  29.       This single stream can then be  interpreted  by  the  prioritized
  30.       linked list of input handlers that are watching the input stream.
  31.  
  32.  
  33.       1.1.  OVERVIEW
  34.  
  35.       The input device is automatically opened by AmigaDOS by any  call
  36.       to  open  the console device.  When the input device is opened, a
  37.       task, appropriately  named  ``input.device'',  is  started.   The
  38.       input  device task communicates directly with the keyboard device
  39.       to obtain raw key inputs.  It also communicates with the gameport
  40.       device  to obtain mouse button and mouse movement events and with
  41.       the timer device to obtain time events.   In  addition  to  these
  42.       event  streams, you can also directly input an event to the input
  43.       device, to be fed to the  handler  chain.   This  topic  is  also
  44.       covered below.
  45.  
  46.       The keyboard device is also accessible directly.  However,  while
  47.       the  input  device task is operating, it attempts to retrieve all
  48.       incoming keyboard events and add them to the input stream.
  49.  
  50.       The gameport device has two units available to it.  As  you  view
  51.       the  Amiga looking at the gameport connectors, connector ``1'' is
  52.       assigned as the primary mouse input for Intuition and contributes
  53.       gameport input events to the input event stream.  Connector ``2''
  54.       is handled by the other gameport  unit  and  is  currently  unas-
  55.       signed.   Each unit of the gameport device is an exclusive access
  56.       object, in that you  can  specify  what  type  of  controller  is
  57.       attached.   It  is  then  assumed  that  only one task is sending
  58.       requests for input from that unit.  While the input  device  task
  59.       is running, that task expects to read the input from connector 1.
  60.       Direct use of the  gameport  device  is  covered  in  a  separate
  61.       chapter of this manual.
  62.  
  63.  
  64.  
  65.  
  66.                               November 13, 1985
  67.  
  68.  
  69.  
  70.  
  71.  
  72.                                     - 2 -
  73.  
  74.  
  75.       The timer device provides time events for the  input  device.  It
  76.       also  provides  time  interval reports for controlling key repeat
  77.       rate and key repeat threshold.  The timer  device  is  a  shared-
  78.       access device and is described in its own separate section.
  79.  
  80.  
  81.       1.2.  INPUT DEVICE COMMANDS
  82.  
  83.       The input device allows the following system functions:
  84.  
  85.  
  86.            COMMAND              OPERATION
  87.  
  88.            OpenDevice()    Obtain  shared  use  of  the  input  device.
  89.            CloseDevice()   Relinquish   use   of   the   input  device.
  90.            DoIO()  Initiate a command, and wait  for  it  to  complete.
  91.            SendIO()        Initiate  a command, and return immediately.
  92.            AbortIO()       Abort a command already in the queue.
  93.  
  94.  
  95.       Only the Start, Stop,  Invalid,  and  Flush  commands  have  been
  96.       implemented   for  this  device.   All  other  commands  are  no-
  97.       operations.
  98.  
  99.       The input device also supports the following device-specific com-
  100.       mands:
  101.  
  102.                          Table 1-1: Input Device Commands
  103.  
  104.  
  105.            I/O COMMAND     OPERATION
  106.  
  107. IND_WRITEEVENT  Propagate an input event stream to all  devices  
  108. IND_ADDHANDLER  Add  an  input-stream handler into the
  109.                 handler  chain.   
  110. IND_REMHANDLER  Remove an input-stream handler from the handler chain.  
  111. IND_SETTHRESH   Set the repeating   key   hold-down time before repeat
  112.                 starts.   
  113. IND_SETPERIOD   Set  the period at which a
  114.                 repeating key repeats. 
  115. IND_SETMPORT    Set the gameport port to which the mouse is connected.
  116. IND_SETTRIGGER  Read conditions that must be met by a  mouse
  117.                 before a pending read request will be satisfied.
  118. IND_SETMTYPE    Set the type of device at the mouse port.
  119.  
  120.  
  121.       The device-specific commands outlined above are described in  the
  122.       following  paragraphs.  A description of the contents of an input
  123.       event is given first because the  input  device  deals  in  input
  124.  
  125.  
  126.                               November 13, 1985
  127.  
  128.  
  129.  
  130.  
  131.  
  132.                                     - 3 -
  133.  
  134.  
  135.       events.  An input event is a data structure that describes:
  136.  
  137.           o   the class of the event-often describes  the  device  that
  138.               generated the event
  139.  
  140.           o   the subclass of the event-space for more  information  if
  141.               needed
  142.  
  143.           o   the  code-keycode  if  keyboard,  button  information  if
  144.               mouse, others
  145.  
  146.           o   a qualifier such as ``ALT key also down'',  ``key  repeat
  147.               active''
  148.  
  149.           o   a position field which contains a data address or a mouse
  150.               position count.
  151.  
  152.           o   a time stamp, showing the sequence in which  events  have
  153.               occurred
  154.  
  155.           o   a link-field by which input events are linked together
  156.  
  157.       The various types of input events are listed in the  include-file
  158.       devices/inputevent.h.   That  information  is  not repeated here.
  159.       You can find more information about input events in the  chapters
  160.       titled ``Gameport Device'' and ``Console Device''.
  161.  
  162.       There is a difference between simply  receiving  an  input  event
  163.       from  a  device  (gameport,  keyboard,  or  console) and actually
  164.       becoming a handler of an input event stream.  A handler is a rou-
  165.       tine  that  is passed an input event, and it is up to the handler
  166.       to decide if it can process the input event.  If the handler does
  167.       not  recognize the event, it passes the address of the event as a
  168.       return value.
  169.  
  170.       Because of the input event field called ie_NextEvent, it is  pos-
  171.       sible for the input event to be a pointer to the first event in a
  172.       linked list of events to be handled.  Thus the handler should  be
  173.       designed  to handle multiple events if such a link is used.  Note
  174.       that handlers can,  themselves,  generate  new  linked  lists  of
  175.       events which can be passed down to lower priority handlers.
  176.  
  177.  
  178.       You add a handler to the chain  by  the  command  IND_ADDHANDLER.
  179.       Assuming  that  you have a properly initialized an IOStdReq block
  180.       as a result of a call to OpenDevice()  (for  the  input  device),
  181.       here is a typical C-language call to the IND_ADDHANDLER function:
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.                               November 13, 1985
  193.  
  194.  
  195.  
  196.  
  197.  
  198.                                     - 4 -
  199.  
  200.  
  201.  
  202.               struct Interrupt handlerStuff;
  203.               handlerStuff.is_Data = &hsData;
  204.                               /* address of its data area */
  205.               handlerStuff.is_Code = myhandler;
  206.                               /* address of entry point to handler */
  207.               handlerStuff.is_Node.ln_Pri = 51;
  208.                               /* set the priority one step higher than
  209.                                * Intution, so that our handler enters
  210.                                * the chain ahead of Intuition.
  211.                                */
  212.               inputRequestBlock.io_Command = IND_ADDHANDLER;
  213.               inputRequestBlock.io_Data = &handlerStuff;
  214.  
  215.               DoIO(&inputRequestBlock);
  216.  
  217.  
  218.       Notice from the above that Intuition is one of the  input  device
  219.       handlers  and  normally  distributes  all  of  the  input events.
  220.       Intuition inserts itself at priority position 50.  You can choose
  221.       the  position in the chain at which your handler will be inserted
  222.       by setting the priority field in the list-node part of the inter-
  223.       rupt data structure you are feeding to this routine.
  224.  
  225.       Note also that any processing time expended  by  a  handler  sub-
  226.       tracts  from  the  time  available before the next event happens.
  227.       Therefore, handlers for the input stream must be fast.
  228.  
  229.  
  230.  
  231.                        Rules for Input Device Handlers
  232.  
  233.       The following rules should be followed when you are designing  an
  234.       input handler:
  235.  
  236.           1.  If an input handler is capable of processing  a  specific
  237.               kind  of  an  input  event  and  that  event has no links
  238.               (ie_NextEvent = 0), the handler can end the handler chain
  239.               by returning a NULL (0) value.
  240.  
  241.           2.  If there are multiple events linked together, the handler
  242.               can  feel  free  to  delink an event from the input event
  243.               chain, thereby passing a shorter list of events to subse-
  244.               quent  handlers.   The  starting  address of the modified
  245.               list is the return value.
  246.  
  247.           3.  If a handler wishes to add new events to the  chain  that
  248.               it  passes to a lower priority handler, it may initialize
  249.               memory to contain the new  event  or  event  chain.   The
  250.               handler,  when it again gets control on the next round of
  251.               event handling, should assume nothing about  the  current
  252.               contents  of  the  memory blocks it attached to the event
  253.               chain.  Lower priority handlers  may  have  modified  the
  254.  
  255.  
  256.  
  257.                               November 13, 1985
  258.  
  259.  
  260.  
  261.  
  262.  
  263.                                     - 5 -
  264.  
  265.  
  266.               memory  as  they  handled  their  part  of the event. The
  267.               handler that allocates the memory for this purpose should
  268.               keep  track  of the starting address and the size of this
  269.               memory chunk so that the memory can be  returned  to  the
  270.               free memory list when it is no longer needed.
  271.  
  272.       Your routine should be structured so that it  can  be  called  as
  273.       though from the following assembler language statement:
  274.  
  275.               newEventChain = yourHandlerCode(oldEventChain, yourHandlerData);
  276.  
  277.       where:
  278.  
  279.           o   yourHandlerCode is the entry point to your routine,
  280.  
  281.           o   oldEventChain is the starting  address  for  the  current
  282.               chain of input events, and
  283.  
  284.           o   newEventChain is the starting address of an  event  chain
  285.               which you are passing to the next handler, if any.
  286.  
  287.       A NULL (0) value terminates the handling.
  288.  
  289.       Memory that you use to describe a new  input  event  that  you've
  290.       added  to the event chain is available for re-use or deallocation
  291.       when the handler is called again or after the IND_REMHANDLER com-
  292.       mand for the handler is complete.
  293.  
  294.       Because IND_ADDHANDLER installs a handler in any position in  the
  295.       handler  chain,  it  can,  for  example, ignore specific types of
  296.       input events as well as act upon and modify existing  streams  of
  297.       input.   It  can  even  create  new input events for Intuition or
  298.       other programs to interpret.
  299.  
  300.  
  301.       You remove a handler from the  handler  chain  with  the  command
  302.       IND_REMHANDLER.   Assuming  that  you have a properly initialized
  303.       IOStdReq block as a result of a call  to  OpenDevice()  (for  the
  304.       input  device)  and  you  have  already  added  the handler using
  305.       IND_ADDHANDLER,  here  is  a  typical  C-language  call  to   the
  306.       IND_REMHANDLER function:
  307.  
  308.               inputRequestBlock.io_Command = IND_REMHANDLER;
  309.               inputRequestBlock.io_Data = &handlerStuff;
  310.                       /* tell it which one to remove */
  311.               DoIO(&inputRequestBlock);
  312.  
  313.  
  314.  
  315.       As noted in the overview of this chapter, input events  are  nor-
  316.       mally  generated by the timer device, keyboard device or gameport
  317.       device.  A user can also generate an input event and send  it  to
  318.       the input device.  It will then be treated as any other event and
  319.       passed through to the input handler chain.  You can  create  your
  320.  
  321.  
  322.  
  323.                               November 13, 1985
  324.  
  325.  
  326.  
  327.  
  328.  
  329.                                     - 6 -
  330.  
  331.  
  332.       own  stream  of  events, then send them to the input device using
  333.       the IND_WRITEEVENT command.   Here  is  an  example,  assuming  a
  334.       correctly  initialized input_request_block.  The example sends in
  335.       a single event, which is a phony mouse-movement:
  336.  
  337.               struct InputEvent phony;
  338.  
  339.               input_request_block.io_Command = IND_WRITEEVENT;
  340.               input_request_block.io_Flags = 0;
  341.               input_request_block.io_Length = sizeof(struct InputEvent);
  342.               input_request_block.io_Data = &phony;
  343.  
  344.               phony.ie_NextEvent = NULL;      /* only one */
  345.               phony.ie_Class = IECLASS_RAWMOUSE;
  346.               phony.ie_TimeStamp.tv_secs = 0;
  347.               phony.ie_TimeStamp.tv_micro = 0;
  348.               phony.ie_Code = IECODE_NOBUTTON;
  349.               phony.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
  350.               phony.ie_X = 10;
  351.               phony.ie_Y = 5;
  352.                               /* mouse didn't move, but program made
  353.                                * system think that it did.
  354.                                */
  355.               DoIO(&input_request_block);
  356.  
  357.  
  358.       NOTE:  This command adds the  input  event  to  the  end  of  the
  359.       current event stream.  The system links other events onto the end
  360.       of this event, thus modifying the contents of the data  structure
  361.       you constructed in the first place.
  362.  
  363.  
  364.       This command sets the timing in seconds and microseconds for  the
  365.       input  device  to  indicate  how long a user must hold down a key
  366.       before it begins to repeat.  This command is  normally  performed
  367.       by  the Preferences tool or by Intuition when it notices that the
  368.       Preferences have been changed.  If you wish, you  can  call  this
  369.       function.   The  following typical sequence assumes that you have
  370.       already correctly initialized the request block  by  opening  the
  371.       input device: Only the fields shown here need be initialized.
  372.  
  373.               struct InputEvent thresh_event;
  374.  
  375.               input_request_block.io_Command = IND_SETTHRESH;
  376.               input_request_block.io_Flags = 0;
  377.               input_request_block.io_Data = &thresh_event;
  378.  
  379.               thresh_event.ie_NextEvent = 0;
  380.               thresh_event.ie_TimeStamp.tv_secs = 1;  /* one second */
  381.               thresh_event.ie_TimeStamp.tv_micro = 500000;
  382.                               /* 500,000 microseconds = 1/2 second */
  383.               DoIO(&input_request_block);
  384.  
  385.  
  386.  
  387.  
  388.  
  389.                               November 13, 1985
  390.  
  391.  
  392.  
  393.  
  394.  
  395.                                     - 7 -
  396.  
  397.  
  398.       This command sets the time period between key repeat events  once
  399.       the  initial  period threshhold has elapsed.  Again, it is a com-
  400.       mand normally issued by Intuition and preset by  the  Preferences
  401.       tool.   A  typical calling sequence is as shown above; change the
  402.       command number and the timing period values to suit your applica-
  403.       tion.
  404.  
  405.  
  406.       1.3.  ADVANCED TOPICS-INPUT DEVICE AND INTUITION
  407.  
  408.       There are several ways to receive information  from  the  various
  409.       devices  that  are part of the input device.  The first way is to
  410.       communicate directly with the device.  This way is, as  specified
  411.       above,  occasionally  undesirable (while the input device task is
  412.       running).  The second way is to become a handler for  the  stream
  413.       of  events  which the input device produces.  That method is also
  414.       shown above.
  415.  
  416.       The third method of getting input from the  input  device  is  to
  417.       retrieve  the  data  from  the  console  device or from the IDCMP
  418.       (Intuition Direct Communications Message Port).
  419.  
  420.       If you choose this third method, you should be aware of what hap-
  421.       pens to input events if your task chooses not to respond to them.
  422.       If there is no active window and no active  console,  then  input
  423.       events  (key  strokes  or  left button mouse clicks usually) will
  424.       simply be ignored.   If,  however,  there  is  an  active  window
  425.       (yours),  and  you  choose  to  simply  let  the messages pile up
  426.       without responding to them as quickly as possible, here  is  what
  427.       happens:
  428.  
  429.           o   Another event occurs.  If the system has no empty message
  430.               that it can fill in to report this new event, then memory
  431.               is dynamically allocated to hold this new information and
  432.               the  new  message  is transmitted to the message port for
  433.               the task.
  434.  
  435.           o   When the task finally responds to the message, the  allo-
  436.               cated  memory isn't returned to the system until the win-
  437.               dow is closed.  Therefore, a task  that  chooses  not  to
  438.               respond  to  its  incoming messages for a long period  of
  439.               time can potentially remove a great deal of  memory  from
  440.               the  system  free  memory  list, making that memory space
  441.               unavailable to this or other tasks  until  this  task  is
  442.               completed.
  443.  
  444.       Thus it is always a good idea to respond  to  input  messages  as
  445.       quickly  as possible to maximize the amount of free memory in the
  446.       system while your task is running.
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.                               November 13, 1985
  455.  
  456.